package tech

//import "fmt"

func (g *Grid) lastOneHouse(house *House) (ok bool, result *Result) {
	if house.solvedCount != 8 {
		return
	}

	for _, cell := range house.cells {
		if cell.solved() {
			continue
		}
		value := toValue(cell.cands.GetList()[0])
		if OUTPUTRESULT {
			result = new(Result)
			result.setChosen(value, cell)
			result.addHelpHouses([]*House{house})
			result.setStrategyName("Last One")
		}
		if CHANGE {
			g.solveOneCell(cell.rowNum, cell.colNum, value)
		}
		ok = true
		return
	}
	return
}

func (s *Solve) LastOne(g *Grid) (used bool, results []*Result) {
	return g.lastOne()
}
func (g *Grid) lastOne() (used bool, results []*Result) {
	for _, house := range g.houses {
		if ok, result := g.lastOneHouse(house); ok {
			used = true
			if OUTPUTRESULT {
				results = append(results, result)
			}
			if !EXHAUSTIVE {
				return
			}
		}
	}
	return
}

func (g *Grid) HiddenSingleHouse(house *House) (ok bool, results []*Result) {
	for cand := range 9 {
		var solved *Cell
		count := 0
		for _, cell := range house.cells {
			if cell.solved() {
				continue
			}
			if cell.cands.Has(cand) {
				count++
				solved = cell
			}
		}
		if count != 1 {
			continue
		}
		ok = true
		value := toValue(cand)
		if OUTPUTRESULT {
			var result Result
			result.setChosen(value, solved)
			result.addHelpHouses([]*House{house})
			result.setStrategyName(house.KindName() + " Hidden Single")
			results = append(results, &result)
		}
		if CHANGE {
			g.solveOneCell(solved.rowNum, solved.colNum, value)
		}
		if !EXHAUSTIVE {
			return
		}
	}

	return
}

func (s *Solve) HiddenSingleBox(g *Grid) (used bool, results []*Result) {
	return g.hiddenSingleBox()
}
func (g *Grid) hiddenSingleBox() (used bool, results []*Result) {
	for _, box := range g.boxes {
		if ok, rs := g.HiddenSingleHouse(&box); ok {
			used = ok
			if OUTPUTRESULT {
				results = append(results, rs...)
			}
			if !EXHAUSTIVE {
				return
			}
		}
	}
	return
}

func (s *Solve) HiddenSingleRow(g *Grid) (used bool, results []*Result) {
	return g.hiddenSingleRow()
}
func (g *Grid) hiddenSingleRow() (used bool, results []*Result) {
	for _, row := range g.rows {
		if ok, rs := g.HiddenSingleHouse(&row); ok {
			used = ok
			if OUTPUTRESULT {
				results = append(results, rs...)
			}
			if !EXHAUSTIVE {
				return
			}
		}
	}
	return
}

func (s *Solve) HiddenSingleCol(g *Grid) (used bool, results []*Result) {
	return g.hiddenSingleCol()
}
func (g *Grid) hiddenSingleCol() (used bool, results []*Result) {
	for _, col := range g.cols {
		if ok, rs := g.HiddenSingleHouse(&col); ok {
			used = ok
			if OUTPUTRESULT {
				results = append(results, rs...)
			}
			if !EXHAUSTIVE {
				return
			}
		}
	}
	return
}

func (s *Solve) NakedSingle(g *Grid) (used bool, results []*Result) {
	for _, cell := range g.allCells {
		if cell.solved() || cell.cands.Count() != 1 {
			continue
		}
		value := toValue(cell.cands.GetList()[0])
		used = true
		if OUTPUTRESULT {
			result := new(Result)
			result.setChosen(value, cell)
			result.setStrategyName("Naked Single")
			results = append(results, result)
		}
		if CHANGE {
			g.solveOneCell(cell.rowNum, cell.colNum, value)
		}
		if !EXHAUSTIVE {
			return
		}
	}
	return
}

//*/
